﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.IO;

namespace Edc.Tfs2MantisGui
{
    static class Program
    {
        private static Edc.MantisClient.Mantis _mantis;
        private static VersionControlServer _versionControl;
        private static Workspace _defaultWorkspace;


        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());

            Run();
        }

        private static void Run()
        {
            _mantis = new Edc.MantisClient.Mantis(Edc.Tfs2MantisGui.Properties.Settings.Default.MantisUrl);

            var server = GetTeamFoundationServer();
            _versionControl = (VersionControlServer)server.GetService(typeof(VersionControlServer));
            _defaultWorkspace = GetDefaultWorkspace(_versionControl);

            
            Edc.MantisClient.Issue issue; 
            using (var formIssue = new FormIssue() { Mantis = _mantis })
            {
                formIssue.ShowDialog();
                if (formIssue.DialogResult != DialogResult.OK) return;
                issue = formIssue.Issue;
            }

            var pendingChanges = GetPendingChanges();
            var changesByProject = GetChangesByProject(pendingChanges);
            foreach (var pendingProject in changesByProject)
            {
                _defaultWorkspace.CheckIn(pendingProject.Value.ToArray(), issue.Summary);
            }
        }

        private static Dictionary<string, List<PendingChange>> GetChangesByProject(PendingChange[] pendingChanges)
        {
            var changesByProject = new Dictionary<string, List<PendingChange>>();
            var assemblyManager = new Edc.MMAssemblyManager.AssemblyManager();
            foreach (var pendingChange in pendingChanges)
            {
                var project = assemblyManager.FindProject(pendingChange.LocalItem);
                if (!changesByProject.ContainsKey(project.FullName))
                {
                    changesByProject[project.FullName] = new List<PendingChange>();
                }

                changesByProject[project.FullName].Add(pendingChange);
            }

            return changesByProject;
        }

        /// <summary>
        /// Restituisce i Pending Changes da considerare per questa applicazione.
        /// </summary>
        /// <returns>Se la riga di comando contiene il percorso di un file, ritorna tutti i file del suo progetto (csproj),
        /// altrimenti tutti i file pendenti.</returns>
        private static PendingChange[] GetPendingChanges()
        {
            // Se l'utente ha specificato un file sulla linea di comando, restituiamo solo i PendingChanges del suo progetto.
            if (Environment.GetCommandLineArgs().Length > 1)
            {
                var pendingFile = Environment.GetCommandLineArgs()[1];
                var assemblyManager = new Edc.MMAssemblyManager.AssemblyManager();
                var csProj = assemblyManager.FindProject(pendingFile);
                return _defaultWorkspace.GetPendingChanges(csProj.DirectoryName, RecursionType.Full);
            }
            else
            {
                return _defaultWorkspace.GetPendingChanges();
            }
        }

        /// <summary>
        /// Restituisce il server di TFS da usare.
        /// </summary>
        /// <returns>Il server di TFS indicato dai settaggi dell'applicazione.</returns>
        private static TeamFoundationServer GetTeamFoundationServer()
        {
            return TeamFoundationServerFactory.GetServer(Edc.Tfs2MantisGui.Properties.Settings.Default.TfsServerUrl, new UICredentialsProvider());
        }

        /// <summary>
        /// Restituisce il workspace di default (dell'utente corrente e della macchina corrente) del server passato.
        /// </summary>
        /// <param name="versionControl">Il server di Version Control</param>
        /// <returns>Il workspace di default.</returns>
        private static Workspace GetDefaultWorkspace(VersionControlServer versionControl)
        {
            return versionControl.QueryWorkspaces(null, versionControl.TeamFoundationServer.AuthenticatedUserName, Environment.MachineName)[0];
        }
    }
}
